home *** CD-ROM | disk | FTP | other *** search
- Subject: v18i027: Mail user's shell version 6.4, Part05/19
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Dan Heller <island!argv@sun.com>
- Posting-number: Volume 18, Issue 27
- Archive-name: mush6.4/part05
-
-
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 5 (of 19)."
- # Contents: doproc.c file.c signals.c strings.c
- # Wrapped by rsalz@papaya.bbn.com on Mon Mar 13 19:25:11 1989
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'doproc.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'doproc.c'\"
- else
- echo shar: Extracting \"'doproc.c'\" \(12131 characters\)
- sed "s/^X//" >'doproc.c' <<'END_OF_FILE'
- X/* @(#)doproc.c (c) copyright 10/18/86 (Dan Heller) */
- X
- X/* do main panel item procedures */
- X#include "mush.h"
- X
- Xrespond_mail(item, value, event)
- XPanel_item item;
- Xint value;
- Xstruct inputevent *event;
- X{
- X char buf[80];
- X
- X if (value == 4)
- X return help(panel_sw->ts_windowfd, "respond", tool_help);
- X if (ison(glob_flags, IS_GETTING)) {
- X print("Finish editing current message first");
- X return;
- X }
- X if (!msg_cnt) {
- X print("No messages to respond to.\n");
- X return;
- X }
- X print("Responding to message %d", current_msg+1);
- X if (event && event->ie_code == MS_LEFT)
- X value = 0;
- X (void) sprintf(buf, "%s %s %d",
- X (value == 2 || value == 3)? "replyall" : "replysender",
- X (value == 1 || value == 3)? "-i": NO_STRING, current_msg+1);
- X (void) cmd_line(buf, msg_list);
- X}
- X
- X/* following macro is for the next two procedures */
- X#define hdr_item (item == sub_hdr_item[0] || item == sub_hdr_item[1] || \
- X item == sub_hdr_item[2] || item == sub_hdr_item[3] || \
- X item == sub_hdr_item[4] || item == sub_hdr_item[5])
- X
- Xdelete_mail(item, value, event)
- Xregister Panel_item item;
- Xint value;
- Xregister struct inputevent *event;
- X{
- X int val = value; /* save cuz we reset value immediately */
- X u_long bang = ison(glob_flags, IGN_BANG);
- X char buf[128];
- X
- X panel_set(item, PANEL_VALUE, 0, 0);
- X if (hdr_item && event->ie_code != MS_LEFT || val == 2)
- X return help(panel_sw->ts_windowfd, "delete", tool_help);
- X /* delete current message */
- X print(sprintf(buf, "%sdelete %s",
- X ((event->ie_code == MS_LEFT || val == 0)? "" : "un"),
- X panel_get_value(msg_num_item)));
- X turnon(glob_flags, IGN_BANG);
- X (void) cmd_line(buf, msg_list);
- X if (!bang)
- X turnoff(glob_flags, IGN_BANG);
- X}
- X
- Xread_mail(item, value, event)
- Xregister Panel_item item;
- Xregister int value;
- Xregister struct inputevent *event;
- X{
- X register int this_msg = current_msg;
- X
- X /* check "event" in case we were called from select.c
- X * in which case event would be NULL
- X */
- X if (event && event->ie_code == MS_RIGHT &&
- X item && (item == read_item && value ||
- X (item == sub_hdr_item[0] || item == sub_hdr_item[1])))
- X return help(panel_sw->ts_windowfd, "next", tool_help);
- X if (item && (item == sub_hdr_item[4] || item == sub_hdr_item[5]))
- X return help(panel_sw->ts_windowfd, "msg_menu", tool_help);
- X if (!msg_cnt) {
- X print ("No Mail.");
- X return -1;
- X }
- X if (item && item == read_item || ison(msg[current_msg].m_flags, DELETE))
- X (void) next_msg();
- X if (this_msg != current_msg || ison(msg[current_msg].m_flags, UNREAD) ||
- X (current_msg < n_array[0] || current_msg > n_array[screen])) {
- X set_isread(current_msg);
- X (void) do_hdrs(0, DUBL_NULL, NULL);
- X }
- X if (isoff(msg[current_msg].m_flags, DELETE))
- X display_msg(current_msg, (long)0);
- X return -1;
- X}
- X
- X/* the panel button that says "filename" and "directory", etc... text item */
- Xfile_dir(item, event)
- XPanel_item item;
- Xstruct inputevent *event;
- X{
- X register char *p;
- X u_long bang = ison(glob_flags, IGN_BANG);
- X char buf[128], *which = panel_get(item, PANEL_LABEL_STRING);
- X
- X if (!strcmp(which, "folder:"))
- X if (event->ie_code == '\n' || event->ie_code == '\r')
- X (void) sprintf(buf, "folder %s", panel_get_value(item));
- X else
- X (void) sprintf(buf, "folder ! %s", panel_get_value(item));
- X
- X else if (!strcmp(which, "directory:"))
- X (void) sprintf(buf, "cd %s", panel_get_value(item));
- X
- X else if (!msg_cnt)
- X print("No messages to save");
- X
- X else if (!strcmp(which, "filename:")) {
- X int x = 1;
- X register char *b = buf;
- X if (event->ie_code == '\n' || event->ie_code == '\r')
- X b += Strcpy(buf, "save ");
- X else
- X b += Strcpy(buf, "write ");
- X if ((p = panel_get_value(msg_num_item)) && *p)
- X b += Strcpy(b, p);
- X else
- X b += strlen(sprintf(b, "%d", current_msg+1));
- X *b++ = ' ', *b = 0;
- X if (!(p = panel_get_value(item)) || !*p &&
- X (!(p = do_set(set_options, "mbox")) || !*p))
- X p = DEF_MBOX;
- X print(buf), print_more("in %s?", p); /* prompt before adding to cmd */
- X (void) strcpy(b, p); /* now add to command */
- X if ((x = confirm(print_sw->ts_windowfd)) != 'y' && x != MS_LEFT) {
- X print("Message not saved");
- X return;
- X }
- X }
- X turnon(glob_flags, IGN_BANG);
- X (void) cmd_line(buf, msg_list);
- X if (!bang)
- X turnoff(glob_flags, IGN_BANG);
- X}
- X
- Xdo_file_dir(item, value, event)
- XPanel_item item;
- Xint value;
- Xstruct inputevent *event;
- X{
- X char buf[92];
- X u_long bang = ison(glob_flags, IGN_BANG);
- X int x; /* used for confirmation */
- X
- X if (item == folder_item) {
- X (void) strcpy(buf, "folder ");
- X if (event->ie_code == MS_LEFT) {
- X print("Current folder is: \"%s\"", mailfile);
- X panel_set(file_item, PANEL_LABEL_STRING, "folder:", 0);
- X panel_set(file_item, PANEL_MENU_CHOICE_STRINGS,
- X "Change without updating current folder", 0, 0);
- X } else {
- X if (!value)
- X (void) strcat(buf, "%");
- X else if (value == 1)
- X (void) strcat(buf, "&");
- X else if (value == 2)
- X (void) strcat(buf, "#");
- X else {
- X (void) sprintf(buf, "folder %s",
- X panel_get(item, PANEL_CHOICE_STRING, value));
- X if (!strcmp(buf+7, "Help"))
- X return help(panel_sw->ts_windowfd, "folder", tool_help);
- X }
- X }
- X } else if (item == cd_item) {
- X (void) strcpy(buf, "cd ");
- X if (event->ie_code == MS_LEFT || !value) {
- X panel_set(file_item, PANEL_LABEL_STRING, "directory:", 0);
- X panel_set(file_item, PANEL_MENU_CHOICE_STRINGS,
- X "Change to specified directory", 0, 0);
- X } else if (value == 1)
- X (void) strcat(buf, "~");
- X else if (value == 2)
- X (void) strcat(buf, "+");
- X else
- X return help(panel_sw->ts_windowfd, "chdir", tool_help);
- X } else if (item == save_item) {
- X (void) strcpy(buf, "save ");
- X if (event->ie_code == MS_LEFT)
- X if (!strcmp("filename:", panel_get(file_item,PANEL_LABEL_STRING))) {
- X event->ie_code = '\n'; /* let file_dir think it got a \n */
- X return file_dir(file_item, event);
- X } else {
- X panel_set(file_item, PANEL_LABEL_STRING, "filename:", 0);
- X panel_set(file_item, PANEL_MENU_CHOICE_STRINGS,
- X "Save message WITHOUT headers", 0,0);
- X print("Type in Main Panel Window a filename to save message");
- X return;
- X }
- X else if (value == 0) {
- X register char *p = panel_get_value(file_item);
- X register char *p2 = panel_get_value(msg_num_item);
- X if ((!p || !*p) && (!(p = do_set(set_options, "mbox")) || !*p))
- X p = DEF_MBOX;
- X print("Save in %s? ", p);
- X if ((x = confirm(panel_sw->ts_windowfd)) != 'y' && x != MS_LEFT) {
- X print("Message not saved");
- X return;
- X }
- X if (p2 && *p2) {
- X (void) strcat(buf, p2);
- X panel_set(msg_num_item, PANEL_VALUE, NO_STRING, 0);
- X (void) strcat(buf, " ");
- X }
- X (void) strcat(buf, p);
- X } else {
- X (void) sprintf(buf, "save %s",
- X panel_get(item, PANEL_CHOICE_STRING, value));
- X if (!strcmp(buf+5, "Help"))
- X return help(panel_sw->ts_windowfd, "save", tool_help);
- X }
- X }
- X turnon(glob_flags, IGN_BANG);
- X (void) cmd_line(buf, msg_list);
- X if (!bang)
- X turnoff(glob_flags, IGN_BANG);
- X panel_set(item, PANEL_VALUE, NO_STRING, 0); /* remove last value */
- X}
- X
- Xtext_done(item, event)
- XPanel_item item;
- Xstruct inputevent *event;
- X{
- X char opt[30], buf[82], cmd[82];
- X register char *p;
- X u_long bang = ison(glob_flags, IGN_BANG);
- X Panel_item which = NO_ITEM;
- X int set_it;
- X
- X if ((event->ie_code == '\n' || event->ie_code == '\r') &&
- X *strcpy(buf, panel_get_value(item))) {
- X (void) strcpy(opt, panel_get(item, PANEL_LABEL_STRING));
- X set_it = (*opt == 'S');
- X if (!(p = index(opt, ' '))) {
- X print("Hmmm... there seems to be a problem here.");
- X return;
- X }
- X ++p;
- X switch(lower(*p)) {
- X case 'o':
- X (void) sprintf(cmd, "%set %s", (set_it)? "s": "uns", buf);
- X which = option_item;
- X when 'i':
- X (void) sprintf(cmd, "%sgnore %s", (set_it)? "i": "uni", buf);
- X which = ignore_item;
- X when 'a':
- X (void) sprintf(cmd, "%slias %s", (set_it)? "a": "una", buf);
- X which = alias_item;
- X otherwise: print("HUH!? (%c)", *p); return;
- X }
- X turnon(glob_flags, IGN_BANG);
- X (void) cmd_line(cmd, msg_list);
- X if (!bang)
- X turnoff(glob_flags, IGN_BANG);
- X }
- X panel_set(input_item, PANEL_VALUE, NO_STRING, 0); /* remove last value */
- X panel_set(item, PANEL_SHOW_ITEM, FALSE, 0);
- X}
- X
- Xdo_help(item, value, event)
- XPanel_item item;
- Xregister int value;
- Xstruct inputevent *event;
- X{
- X register char *p, *helpfile = tool_help;
- X switch(value) {
- X case 1: p = "help";
- X when 2: p = "mouse";
- X when 3: p = "windows";
- X when 4: p = "function keys";
- X when 5: p = "hdr_format", helpfile = cmd_help;
- X when 6: p = "msg_list", helpfile = cmd_help;
- X otherwise: p = "general";
- X }
- X (void) help(panel_sw->ts_windowfd, p, helpfile);
- X}
- X
- Xtoolquit(item, value, event)
- XPanel_item item;
- Xint value;
- Xstruct inputevent *event;
- X{
- X register int which;
- X
- X if (!value || event->ie_code == MS_LEFT) {
- X if (ison(glob_flags, DO_UPDATE)) {
- X do_update(NO_ITEM, 0, NO_EVENT);
- X turnoff(glob_flags, NEW_MAIL);
- X mail_status(0); /* lower flag (if up) print current num of msgs */
- X }
- X wmgr_changestate (tool->tl_windowfd, rootfd, TRUE);
- X wmgr_changelevel (tool->tl_windowfd, parentfd, TRUE);
- X return;
- X } else if (value == 2) {
- X (void) help(panel_sw->ts_windowfd, "quit", tool_help);
- X return;
- X }
- X print("Left updates changes. Middle does not. Right aborts quit.");
- X if ((which = confirm(panel_sw->ts_windowfd)) == MS_RIGHT) {
- X print("Quit aborted.");
- X return;
- X }
- X abort_mail(NO_ITEM, 0);
- X if (which == MS_LEFT)
- X lock_cursors(), copyback();
- X else
- X print("Bye bye");
- X cleanup(0);
- X}
- X
- Xdo_lpr(item, value, event)
- XPanel_item item;
- Xint value;
- Xstruct inputevent *event;
- X{
- X char buf[128];
- X
- X if (event && (event->ie_code == MS_LEFT || value == 1)) {
- X print("Sending message %d to printer...", current_msg+1);
- X (void) strcpy(buf, "lpr ");
- X if (value)
- X (void) sprintf(buf, "lpr \"%s\"", panel_get_value(msg_num_item));
- X lock_cursors();
- X (void) cmd_line(buf, msg_list);
- X unlock_cursors();
- X } else
- X (void) help(panel_sw->ts_windowfd, "printer", tool_help);
- X}
- X
- Xdo_clear()
- X{
- X /* actions that clears window indicates user wants to quit getting opts */
- X if (msg_pix)
- X pr_destroy(msg_pix), msg_pix = (struct pixrect *)NULL;
- X if (getting_opts)
- X getting_opts = 0, unlock_cursors();
- X pw_writebackground(msg_win, 0,0, msg_rect.r_width,msg_rect.r_height,
- X PIX_CLR);
- X txt.x = 5, txt.y = l_height(curfont) - 1;
- X}
- X
- Xdo_update(item, value, event)
- XPanel_item item;
- Xregister int value;
- Xstruct inputevent *event;
- X{
- X char *argv[2];
- X if (event && event->ie_code != MS_LEFT)
- X return help(panel_sw->ts_windowfd, "update", tool_help);
- X argv[0] = "update";
- X argv[1] = NULL;
- X (void) folder(0, argv, NULL);
- X}
- X
- X/* panel selction button to send a letter.
- X * add a CR if necessary, and finish up letter
- X */
- Xdo_send(item, value, event)
- XPanel_item item;
- Xregister int value;
- Xregister struct inputevent *event;
- X{
- X if (event->ie_code != MS_LEFT)
- X return help(panel_sw->ts_windowfd, "send", tool_help);
- X if (txt.x > 5) {
- X type_cursor(PIX_CLR);
- X add_to_letter(rite('\n')); /* if line isn't complete, flush it */
- X }
- X finish_up_letter();
- X}
- X
- Xdo_edit(item, value, event)
- XPanel_item item;
- Xregister int value;
- Xregister struct inputevent *event;
- X{
- X char buf[4];
- X if (event->ie_code != MS_LEFT)
- X return help(panel_sw->ts_windowfd, "edit", tool_help);
- X if (txt.x > 5)
- X add_to_letter(rite('\n')); /* flush line for him */
- X add_to_letter(sprintf(buf, "%cv", *escape));
- X}
- X
- Xdo_compose(item, value, event)
- XPanel_item item;
- Xregister int value;
- Xstruct inputevent *event;
- X{
- X if (event && event->ie_code != MS_LEFT)
- X return help(panel_sw->ts_windowfd, "compose", tool_help);
- X print("Composing letter.");
- X win_setcursor(msg_sw->ts_windowfd, &write_cursor);
- X clear_msg_list(msg_list);
- X do_mail(0, DUBL_NULL, msg_list);
- X}
- X
- Xchange_font(item, value, event)
- XPanel_item item;
- Xregister int value;
- Xstruct inputevent event;
- X{
- X if (ison(glob_flags, IS_GETTING))
- X type_cursor(PIX_XOR);
- X curfont = value % total_fonts;
- X print("New font: %s\n",
- X (!curfont)? "Normal": (curfont == 1)? "Small": "Large");
- X if (ison(glob_flags, IS_GETTING))
- X type_cursor(PIX_XOR);
- X crt = msg_rect.r_height / l_height(curfont);
- X}
- END_OF_FILE
- if test 12131 -ne `wc -c <'doproc.c'`; then
- echo shar: \"'doproc.c'\" unpacked with wrong size!
- fi
- # end of 'doproc.c'
- fi
- if test -f 'file.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'file.c'\"
- else
- echo shar: Extracting \"'file.c'\" \(9633 characters\)
- sed "s/^X//" >'file.c' <<'END_OF_FILE'
- X/* file.c -- Copyright (1988) Dan Heller */
- X
- X#include "mush.h"
- X#include <pwd.h>
- X
- X/* takes string 'p' and address of int (isdir). If p uses the ~ to reference
- X * a home directory of some sort, then expand it. find out what sort of
- X * file final path is. set isdir to 1 if a directory, 0 if not, -1 on error
- X * return final path. If an error occurs, return string indicating error.
- X * if isdir has a value of 1 when passed, it ignores "No such file or directory"
- X */
- Xchar *
- Xgetpath(p, isdir)
- Xregister char *p;
- Xint *isdir;
- X{
- X static char buf[BUFSIZ];
- X struct stat stat_buf;
- X
- X if (!p || !*p || !strcmp(p, "~")) {
- X char *home = do_set(set_options, "home");
- X if (!home || !*home)
- X home = ALTERNATE_HOME;
- X (void) strcpy(buf, home); /* no arg means home */
- X } else if (*p == '~') {
- X if (p[1] != '/') {
- X /* not our home, but someone else's
- X * look for ~user or ~user/subpath
- X * if '/' exists, separate into tmp="user" p="subpath"
- X */
- X struct passwd *ent, *getpwnam();
- X char *p2 = p+1;
- X if (p = index(p2, '/'))
- X *p++ = 0;
- X if (!(ent = getpwnam(p2))) {
- X *isdir = -1;
- X return sprintf(buf, "no such user: %s", p2);
- X }
- X /* append subpath to pathname */
- X if (p && *p)
- X (void) sprintf(buf, "%s/%s", ent->pw_dir, p);
- X /* if *p == NULL, pathname is done (buf), set isdir = 1 */
- X else {
- X *isdir = 1;
- X return strcpy(buf, ent->pw_dir);
- X }
- X } else {
- X char *home = do_set(set_options, "home");
- X if (!home || !*home)
- X home = ALTERNATE_HOME;
- X (void) sprintf(buf, "%s/%s", home, p+2);
- X }
- X } else if (*p == '%') {
- X /* if %user, append user name... else, it's just us */
- X if (!*++p || *p == ' ' || *p == '\t')
- X (void) strcpy(buf, spoolfile);
- X else
- X#ifndef HOMEMAIL
- X (void) sprintf(buf, "%s/%s", MAILDIR, p);
- X#else /* HOMEMAIL */
- X {
- X char *p2 = do_set(set_options, "home");
- X (void) sprintf(buf, "%s/%s", p2 ? p2 : ALTERNATE_HOME, MAILFILE);
- X } else {
- X int t_isdir = *isdir;
- X char *t, tmp[256];
- X (void) sprintf(tmp, "~%s/%s", p, MAILFILE);
- X t = getpath(tmp, &t_isdir);
- X if (t_isdir == -1) {
- X *isdir = -1;
- X return t;
- X }
- X /* strcpy(buf, t); --buf already has info because it's static */
- X }
- X#endif /* HOMEMAIL */
- X } else if (*p == '+') {
- X register char *p2 = do_set(set_options, "folder");
- X if (!p2 || !*p2)
- X p2 = DEF_FOLDER;
- X (void) sprintf(buf, "%s/%s", p2, ++p);
- X if (*buf != '/') {
- X int t_isdir = *isdir;
- X char *t, tmp[256];
- X if (*buf != '~')
- X (void) sprintf(tmp, "~/%s", buf);
- X else
- X (void) strcpy(tmp, buf);
- X t = getpath(tmp, &t_isdir);
- X if (t_isdir == -1) {
- X *isdir = -1;
- X return t;
- X }
- X /* strcpy(buf, t); --buf already has info because it's static */
- X }
- X } else { /* allow \ to escape the special chars, +, %, ~ */
- X if (*p == '\\')
- X p++;
- X (void) strcpy(buf, p);
- X }
- X if (stat(buf, &stat_buf)) {
- X (void) access(buf, F_OK); /* set errno to the "real" reason */
- X if (errno == ENOENT && *isdir == 1) {
- X *isdir = 0; /* say it's a regular file even tho it doesn't exist */
- X return buf; /* it may be wanted for creating */
- X }
- X *isdir = -1;
- X return sys_errlist[errno];
- X }
- X *isdir = ((stat_buf.st_mode & S_IFDIR) != 0);
- X return buf;
- X}
- X
- X/*
- X * Given a filename[pointer] (p), a file pointer, and a mode, file_to_fp
- X * opens the file with the mode.
- X * If the mode is "r" then we read the file into the file pointer at the
- X * end (fseek(fp, 2, 0)). If the file is opened for writing, then read
- X * from the beginning of fp and write it into the file.
- X * This is usually called to read .signatures into messages (thus,
- X * opening .signature with "r" and writing to the end of fp which is probably
- X * the sendmail process or the message file pointer) or to write fortunes into
- X * the message buffer: reading fp (the popened fortune) and writing into file.
- X */
- Xvoid
- Xfile_to_fp(p, fp, mode)
- Xregister char *p;
- Xregister FILE *fp;
- Xchar *mode;
- X{
- X int x = 1;
- X char *file, buf[BUFSIZ];
- X FILE *tmp_fp;
- X
- X if (!p || !*p) {
- X print("specify filename");
- X return;
- X }
- X file = getpath(p, &x);
- X if (x == -1) { /* on error, file contains error message */
- X wprint(file);
- X return;
- X }
- X wprint("%s: ", file);
- X if (x) /* if x == 1, then path is a directory */
- X wprint("directory.\n");
- X else if (!(tmp_fp = fopen(file, mode))) {
- X wprint("%s\n", sys_errlist[errno]);
- X return;
- X } else if (*mode != 'r') {
- X rewind(fp);
- X for(x = 0; fgets(buf, BUFSIZ, fp); x++)
- X fputs(buf, tmp_fp);
- X } else
- X for(x = 0; fgets(buf, BUFSIZ, tmp_fp); x++)
- X fputs(buf, fp);
- X wprint("%s%d line%s\n", (*mode == 'a')? "added ": "",
- X x, (x == 1)? "": "s");
- X fflush(fp);
- X fclose(tmp_fp);
- X}
- X
- X/* clear all contents of the file. Careful that the file is opened for
- X * _writing_ --tempfile is opened for reading, so don't try to empty it
- X * if you're using ftruncate. Return -1 on error, 0 on success.
- X */
- Xemptyfile(fp, fname)
- Xregister FILE **fp;
- Xregister char *fname;
- X{
- X Debug("Emptying \"%s\"\n", fname);
- X#ifndef SYSV
- X return ftruncate(fileno(*fp), 0L);
- X#else
- X {
- X int omask = umask(077), ret;
- X fclose(*fp);
- X if (!(*fp = fopen(fname, "w")))
- X ret = -1;
- X ret = 0;
- X (void) umask(omask);
- X return ret;
- X }
- X#endif /* SYSV */
- X}
- X
- X/*
- X * Finds out how many file descriptors are opened. Useful for making sure
- X * no files got opened in subprocedures which were not subsequently closed.
- X */
- Xnopenfiles(argc)
- X{
- X register int nfiles = 0;
- X#ifdef MAXFILES
- X register int size = MAXFILES;
- X#else
- X register int size = getdtablesize();
- X#endif /* MAXFILES */
- X
- X if (argc < 2)
- X print("open file descriptors:");
- X while (--size >= 0)
- X if (fcntl(size, F_GETFL, 0) != -1) {
- X if (argc < 2)
- X print_more(" %d", size);
- X ++nfiles;
- X }
- X if (argc < 2)
- X print("\n");
- X return nfiles;
- X}
- X
- X/*
- X * Close all "extraneous" file descriptors; return the number closed
- X */
- Xclosefileds (n)
- X{
- X register int nfiles = 0;
- X#ifdef MAXFILES
- X register int size = MAXFILES;
- X#else
- X register int size = getdtablesize();
- X#endif /* MAXFILES */
- X
- X while (--size >= n)
- X if (fcntl(size, F_GETFL, 0) != -1) {
- X (void) close(size);
- X ++nfiles;
- X }
- X return nfiles;
- X}
- X
- X/*
- X * Open a path for writing or appending -- return a FILE pointer.
- X * If program is TRUE, then use popen, not fopen and don't check
- X * to see if the file is writable.
- X */
- XFILE *
- Xopen_file(p, program)
- Xregister char *p;
- X{
- X register FILE *newfile = NULL_FILE;
- X register char *tmp;
- X int x = 1;
- X
- X if (program || *p == '/')
- X tmp = p, x = 0;
- X else
- X tmp = getpath(p, &x);
- X if (x == 1)
- X print("%s is a directory.\n", tmp);
- X else if (x == -1)
- X print("%s: %s\n", p, tmp);
- X else {
- X register char *mode = NULL;
- X /* if it doesn't exist open for "w" */
- X if (program || Access(tmp, F_OK))
- X mode = "w";
- X /* if we can't write to it, forget it */
- X else if (Access(tmp, W_OK))
- X error(tmp);
- X else
- X mode = "a";
- X if (mode)
- X if (program) {
- X if (!(newfile = popen(tmp, mode))) {
- X error("Can't execute %s\n", tmp);
- X return newfile;
- X }
- X } else
- X if (!(newfile = mask_fopen(tmp, mode)))
- X error("Can't write to %s", tmp);
- X else
- X Debug("Successfully opened %s\n", tmp);
- X }
- X return newfile;
- X}
- X
- X/*
- X * find_files gets a set of addresses and an array of
- X * file pointers and the maximum size that array can be.
- X * The object is to find the files or programs listed in "s", attempt
- X * to fopen/popen them and save their file pointers in the array. If the
- X * size is 0, then just extract the file names and give error messages
- X * for each one since they will not be opened. Return the number of
- X * files opened and delete all files (opened or not) from the list in
- X * "s". Tokens beginning with a "/, ~, or + are files; tokens beginning
- X * with a | are programs.
- X * The string "s" is modified to be a list of address -- all names AND
- X * files are stripped out of the list.
- X */
- Xfind_files(s, files, size)
- Xregister char *s;
- XFILE *files[];
- X{
- X register int total = 0, prog;
- X char file[MAXPATHLEN], buf[HDRSIZ], *start = s, c;
- X register char *p, *b = buf;
- X
- X do {
- X if (!(p = get_name_n_addr(s, NULL, file)))
- X break;
- X c = *p, *p = 0;
- X /* It's a file -- try to open it. This doesn't get written back
- X * onto "buf" since it is supposed to be extracted anyway.
- X */
- X if (*file == '+' || *file == '~' || *file == '|' || *file == '/') {
- X prog = (*file == '|');
- X if (size && total < size) {
- X /* either open "file" or &file[1] */
- X if (files[total] = open_file(&file[prog], prog))
- X total++;
- X } else
- X print("No open space for %s\n", file);
- X } else {
- X b += Strcpy(b, s);
- X *b++ = ',', *b++ = ' ';
- X }
- X for (*p = c, s = p; *s == ',' || isspace(*s); s++)
- X ;
- X } while (*s);
- X for (*b-- = 0; b > buf && (*b == ',' || isspace(*b)); b--)
- X *b = 0;
- X (void) strcpy(start, buf);
- X return total;
- X}
- X
- X/*
- X * access(2) has an undocumented feature which ignores suid. If you are
- X * su'ed and try to read your mail, you will be unable to because access()
- X * will give the illusion that you cannot read/write to your mbox. Solve
- X * the problem by using stat() instead.
- X */
- XAccess(file, mode)
- Xregister char *file;
- X{
- X struct stat buf;
- X
- X if (stat(file, &buf) == -1)
- X return -1;
- X if (mode == R_OK)
- X return (buf.st_mode & 0400)? 0 : -1;
- X if (mode == W_OK)
- X return (buf.st_mode & 0200)? 0 : -1;
- X return 0;
- X}
- X
- X/*
- X * Open a file for read/write/whatever but make sure umask is rw by user only.
- X */
- XFILE *
- Xmask_fopen(file, mode)
- Xchar *file, *mode;
- X{
- X int omask = umask(077);
- X FILE *fp = fopen(file, mode);
- X (void) umask(omask);
- X return fp;
- X}
- END_OF_FILE
- if test 9633 -ne `wc -c <'file.c'`; then
- echo shar: \"'file.c'\" unpacked with wrong size!
- fi
- # end of 'file.c'
- fi
- if test -f 'signals.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'signals.c'\"
- else
- echo shar: Extracting \"'signals.c'\" \(10419 characters\)
- sed "s/^X//" >'signals.c' <<'END_OF_FILE'
- X/* @(#)signals.c (c) copyright 10/18/86 (Dan Heller) */
- X
- X#include "mush.h"
- X
- X#ifndef SYSV
- Xextern char *sys_siglist[];
- X#else
- X/* sys-v doesn't have normal sys_siglist */
- Xstatic char *sys_siglist[] = {
- X/* no error */ "no error",
- X/* SIGHUP */ "hangup",
- X/* SIGINT */ "interrupt (rubout)",
- X/* SIGQUIT */ "quit (ASCII FS)",
- X/* SIGILL */ "illegal instruction (not reset when caught)",
- X/* SIGTRAP */ "trace trap (not reset when caught)",
- X/* SIGIOT */ "IOT instruction",
- X/* SIGEMT */ "EMT instruction",
- X/* SIGFPE */ "floating point exception",
- X/* SIGKILL */ "kill (cannot be caught or ignored)",
- X/* SIGBUS */ "bus error",
- X/* SIGSEGV */ "segmentation violation",
- X/* SIGSYS */ "bad argument to system call",
- X/* SIGPIPE */ "write on a pipe with no one to read it",
- X/* SIGALRM */ "alarm clock",
- X/* SIGTERM */ "software termination signal from kill",
- X/* SIGUSR1 */ "user defined signal 1",
- X/* SIGUSR2 */ "user defined signal 2",
- X/* SIGCLD */ "death of a child",
- X/* SIGPWR */ "power-fail restart"
- X};
- X#endif /* SYSV */
- X
- X#ifdef SUNTOOL
- Xmsgwin_handlesigwinch()
- X{
- X register struct rect rect;
- X if (exec_pid)
- X return;
- X rect = msg_rect;
- X pw_damaged(msg_win);
- X /* this prevents old screen from being lost when editor finishes */
- X if (isoff(glob_flags, IS_GETTING))
- X gfxsw_interpretesigwinch(msg_sw->ts_data);
- X gfxsw_handlesigwinch(msg_sw->ts_data);
- X pw_repairretained(msg_win);
- X pw_donedamaged(msg_win);
- X win_getrect(msg_sw->ts_windowfd, &msg_rect);
- X crt = msg_rect.r_height / l_height(curfont);
- X if (rect.r_height != msg_rect.r_height || rect.r_width != rect.r_width)
- X if (getting_opts == 1)
- X display_opts(0);
- X else if (getting_opts == 2)
- X set_fkeys();
- X else if (msg_pix)
- X scroll_win(0);
- X}
- X
- Xhdrwin_handlesigwinch()
- X{
- X register struct rect rect;
- X rect = hdr_rect;
- X pw_damaged(hdr_win);
- X gfxsw_interpretesigwinch(hdr_sw->ts_data);
- X gfxsw_handlesigwinch(hdr_sw->ts_data);
- X pw_repairretained(hdr_win);
- X pw_donedamaged(hdr_win);
- X win_getrect(hdr_sw->ts_windowfd, &hdr_rect);
- X if (rect.r_width != hdr_rect.r_width || rect.r_height != hdr_rect.r_height){
- X pw_writebackground(hdr_win, 0,0,
- X hdr_rect.r_width, hdr_rect.r_height, PIX_CLR);
- X screen = hdr_rect.r_height/l_height(DEFAULT);
- X (void) do_hdrs(0, DUBL_NULL, NULL);
- X }
- X}
- X
- Xprint_sigwinch()
- X{
- X pw_damaged(print_win);
- X gfxsw_handlesigwinch(print_sw->ts_data);
- X pw_writebackground(print_win, 0,0,
- X win_getwidth(print_sw->ts_windowfd),
- X win_getheight(print_sw->ts_windowfd), PIX_CLR);
- X pw_donedamaged(print_win);
- X print(NULL); /* reprint whatever was there before damage */
- X}
- X
- XSIGRET
- Xsigwinchcatcher()
- X{
- X tool_sigwinch(tool);
- X}
- X#endif /* SUNTOOL */
- X
- XSIGRET
- Xintrpt(sig)
- X{
- X Debug("interrupt() caught: %d\n", sig);
- X mac_flush();
- X turnon(glob_flags, WAS_INTR);
- X}
- X
- X/*
- X * catch signals to reset state of the machine. Always print signal caught.
- X * If signals are ignored, return. If we're running the shell, longjmp back.
- X */
- X/*ARGSUSED*/
- XSIGRET
- Xcatch(sig)
- X{
- X Debug("Caught signal: %d\n", sig);
- X (void) signal(sig, catch);
- X if (ison(glob_flags, IGN_SIGS) && sig != SIGTERM && sig != SIGHUP)
- X return;
- X mac_flush();
- X print("%s: %s\n", prog_name, sys_siglist[sig]);
- X turnoff(glob_flags, IS_PIPE);
- X if (istool || sig == SIGTERM || sig == SIGHUP) {
- X if (istool) /* istool is 2 if tool is complete */
- X istool = 1;
- X (void) setjmp(jmpbuf);
- X if (ison(glob_flags, IS_GETTING))
- X rm_edfile(-1);
- X cleanup(sig);
- X }
- X if (ison(glob_flags, DO_SHELL)) {
- X /* wrapcolumn may have been trashed -- restore it */
- X if (ison(glob_flags, IS_GETTING)) {
- X char *fix = do_set(set_options, "wrapcolumn");
- X if (fix && *fix)
- X wrapcolumn = atoi(fix);
- X }
- X turnoff(glob_flags, IS_GETTING);
- X longjmp(jmpbuf, 1);
- X } else
- X puts("exiting"), cleanup(sig);
- X}
- X
- X#ifdef SIGCONT
- XSIGRET
- Xstop_start(sig)
- X{
- X extern FILE *ed_fp;
- X
- X Debug("Caught signal: %d", sig);
- X if (sig == SIGCONT) {
- X (void) signal(SIGTSTP, stop_start);
- X (void) signal(SIGCONT, stop_start);
- X echo_off();
- X if (istool || ison(glob_flags, IGN_SIGS) && !iscurses)
- X return;
- X /* we're not in an editor but we're editing a letter */
- X if (ison(glob_flags, IS_GETTING)) {
- X if (ed_fp)
- X print("(Continue editing letter)\n");
- X }
- X#ifdef CURSES
- X else if (iscurses)
- X if (ison(glob_flags, IGN_SIGS)) {
- X clr_bot_line();
- X if (msg_list)
- X puts(compose_hdr(current_msg));
- X mail_status(1), addstr("...continue... ");
- X refresh();
- X } else {
- X int curlin = max(1, current_msg - n_array[0] + 1);
- X redraw();
- X print("Continue");
- X move(curlin, 0);
- X refresh();
- X /* make sure we lose reverse video on continuation */
- X if (ison(glob_flags, REV_VIDEO) && msg_cnt) {
- X char buf[256];
- X (void) strncpy(buf, compose_hdr(current_msg), COLS-1);
- X buf[COLS-1] = 0; /* strncpy does not null terminate */
- X mvaddstr(curlin, 0, buf);
- X }
- X }
- X#endif /* CURSES */
- X else
- X mail_status(1), fflush(stdout);
- X } else {
- X#ifdef CURSES
- X if (iscurses) {
- X /* when user stops mush, the current header is not in reverse
- X * video -- note that a refresh() has not been called in curses.c!
- X * so, make sure that when a continue is called, the reverse video
- X * for the current message returns.
- X */
- X turnon(glob_flags, WAS_INTR);
- X if (isoff(glob_flags, IGN_SIGS) && ison(glob_flags, REV_VIDEO) &&
- X msg_cnt) {
- X int curlin = max(1, current_msg - n_array[0] + 1);
- X char buf[256];
- X scrn_line(curlin, buf);
- X STANDOUT(curlin, 0, buf);
- X }
- X print("Stopping...");
- X }
- X#endif /* CURSES */
- X echo_on();
- X (void) signal(SIGTSTP, SIG_DFL);
- X (void) signal(SIGCONT, stop_start);
- X (void) kill(getpid(), sig);
- X }
- X}
- X#endif /* SIGCONT */
- X
- X/*ARGSUSED*/
- Xvoid
- Xcleanup(sig)
- X{
- X char buf[128], c;
- X if (sig != SIGTERM && sig != SIGHUP && ison(glob_flags, IGN_SIGS))
- X c = 'n';
- X else
- X c = 'y';
- X
- X#ifdef CURSES
- X if (iscurses)
- X iscurses = FALSE, endwin();
- X#endif /* CURSES */
- X
- X echo_on();
- X
- X if (ison(glob_flags, IS_GETTING))
- X turnoff(glob_flags, IS_GETTING), dead_letter();
- X if ((sig == SIGSEGV || sig == SIGBUS) && isoff(glob_flags, IGN_SIGS)
- X && *tempfile) {
- X fprintf(stderr, "remove %s [y]? ", tempfile), fflush(stderr);
- X if (fgets(buf, sizeof(buf), stdin))
- X c = lower(*buf);
- X }
- X if (c != 'n' && *tempfile && unlink(tempfile) && !sig && errno != ENOENT)
- X error(tempfile);
- X if (sig == SIGSEGV || sig == SIGBUS) {
- X if (isoff(glob_flags, IGN_SIGS)) {
- X fprintf(stderr, "coredump [n]? "), fflush(stderr);
- X if (fgets(buf, sizeof(buf), stdin))
- X c = lower(*buf);
- X }
- X if (c == 'y')
- X puts("dumping core for debugging"), abort();
- X }
- X exit(sig);
- X}
- X
- Xlong last_spool_size = -1; /* declared here cuz it's initialized here */
- X
- X/*
- X * if new mail comes in, print who it's from. sprintf it all into one
- X * buffer and print that instead of separate print statements to allow
- X * the tool mode to make one print statement. The reason for this is that
- X * when the tool is refreshed (caused by a resize, reopen, move, top, etc)
- X * the last thing printed is displayed -- display the entire line.
- X * return 0 if no new mail, 1 if new mail and -1 if new mail is in system
- X * folder, but current mbox is not system mbox.
- X */
- Xcheck_new_mail()
- X{
- X int ret_value;
- X char buf[BUFSIZ];
- X register char *p = buf;
- X
- X#ifdef SUNTOOL
- X static int is_iconic, was_iconic;
- X
- X if (istool) {
- X timerclear(&(mail_timer.it_interval));
- X timerclear(&(mail_timer.it_value));
- X mail_timer.it_value.tv_sec = time_out;
- X setitimer(ITIMER_REAL, &mail_timer, NULL);
- X }
- X#endif /* SUNTOOL */
- X /* if fullscreen access in progress (help), don't do anything */
- X if (ret_value = mail_size()) {
- X#ifdef CURSES
- X int new_hdrs = last_msg_cnt;
- X#endif /* CURSES */
- X#ifdef SUNTOOL
- X /* if our status has changed from icon to toolform, then
- X * there will already be a message stating number of new
- X * messages. reset `n' to msg_cnt so we don't restate
- X * the same # of new messages upon receipt of yet another new message.
- X */
- X if (istool && !(is_iconic = (tool->tl_flags&TOOL_ICONIC)) && was_iconic)
- X last_msg_cnt = msg_cnt;
- X#endif /* SUNTOOL */
- X if (last_spool_size > spool_size) {
- X wprint("Someone changed \"%s\"! Reinitializing...\n", mailfile);
- X if (isoff(glob_flags, READ_ONLY))
- X (void) emptyfile(&tmpf, tempfile);
- X msg_cnt = 0;
- X }
- X (void) load_folder(mailfile, 1, NULL);
- X if (msg_cnt < last_msg_cnt)
- X turnoff(glob_flags, NEW_MAIL);
- X else
- X turnon(glob_flags, NEW_MAIL);
- X if (istool) {
- X mail_status(0);
- X (void) do_hdrs(0, DUBL_NULL, NULL);
- X bell();
- X }
- X if (msg_cnt < last_msg_cnt) {
- X last_msg_cnt = msg_cnt;
- X last_spool_size = spool_size;
- X if (!istool)
- X mail_status(0);
- X return 0;
- X }
- X p += Strcpy(p, "New mail ");
- X if (msg_cnt - last_msg_cnt <= 1)
- X p += strlen(sprintf(p, "(#%d) ", msg_cnt));
- X else
- X p += strlen(sprintf(p, "(#%d thru #%d)\n", last_msg_cnt+1,msg_cnt));
- X#ifdef SUNTOOL
- X /*
- X * If mush is in tool mode and in icon form, don't update
- X * last_msg_cnt so that when the tool is opened, print() will
- X * print the correct number of "new" messages.
- X */
- X if (!istool || !(was_iconic = tool->tl_flags & TOOL_ICONIC))
- X#endif /* SUNTOOL */
- X if (iscurses && isoff(glob_flags, CNTD_CMD))
- X last_msg_cnt = msg_cnt;
- X else while (last_msg_cnt < msg_cnt) {
- X char *p2 = compose_hdr(last_msg_cnt++) + 9;
- X if (strlen(p2) + (p - buf) >= BUFSIZ-5) {
- X (void) strcat(p, "...\n");
- X /* force a break by setting last_msg_cnt correctly */
- X last_msg_cnt = msg_cnt;
- X } else
- X p += strlen(sprintf(p, " %s\n", p2));
- X }
- X#ifdef CURSES
- X if (iscurses && isoff(glob_flags, CNTD_CMD)) {
- X if (new_hdrs - n_array[screen-1] < screen)
- X (void) do_hdrs(0, DUBL_NULL, NULL);
- X print("%s ...", buf);
- X } else
- X#endif /* CURSES */
- X print("%s", buf); /* buf might have %'s in them!!! */
- X } else
- X#ifdef SUNTOOL
- X if (!istool || !is_iconic)
- X#endif /* SUNTOOL */
- X turnoff(glob_flags, NEW_MAIL);
- X if (last_spool_size > -1 && /* handle first case */
- X strcmp(mailfile, spoolfile) && last_spool_size < spool_size)
- X print("You have new mail in your system mailbox.\n"), ret_value = -1;
- X last_spool_size = spool_size;
- X return ret_value;
- X}
- X
- X/*ARGSUSED*/ /* we ignore the sigstack, cpu-usage, etc... */
- XSIGRET
- Xbus_n_seg(sig)
- X{
- X (void) signal(sig, SIG_DFL);
- X fprintf(stderr, "%s: %s\n", prog_name,
- X (sig == SIGSEGV)? "Segmentation violation": "Bus error");
- X cleanup(sig);
- X}
- END_OF_FILE
- if test 10419 -ne `wc -c <'signals.c'`; then
- echo shar: \"'signals.c'\" unpacked with wrong size!
- fi
- # end of 'signals.c'
- fi
- if test -f 'strings.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'strings.c'\"
- else
- echo shar: Extracting \"'strings.c'\" \(9787 characters\)
- sed "s/^X//" >'strings.c' <<'END_OF_FILE'
- X/* strings.c Copyright(1988) Dan Heller */
- X
- X#include "mush.h"
- X
- X/*
- X * reverse a string. Useful for uucp-style address comparisons.
- X */
- Xchar *
- Xreverse(s)
- Xchar s[];
- X{
- X int n = strlen(s), m;
- X char c;
- X
- X if (n < 1)
- X return;
- X if (n & 1)
- X n = n/2 + 1, m = n - 2;
- X else
- X n /= 2, m = n - 1;
- X for ( ; m >= 0; m--, n++)
- X c = s[n], s[n] = s[m], s[m] = c;
- X return s;
- X}
- X
- X/*
- X * lose the newline character, trailing whitespace, and return the end of p
- X * test for '\n' separately since some _ctype_[] arrays may not have the
- X * _S bit set for the newline character. see <ctype.h> for more info.
- X */
- Xchar *
- Xno_newln(p)
- Xregister char *p;
- X{
- X register char *p2 = p + strlen(p); /* point it to the null terminator */
- X
- X while (p2 > p && *--p2 == '\n' || isspace(*p2))
- X *p2 = 0; /* get rid of newline and trailing spaces */
- X return p2;
- X}
- X
- X/* find any character in s1 that's in s2; return pointer to char in s1. */
- Xchar *
- Xany(s1, s2)
- Xregister char *s1, *s2;
- X{
- X register char *p;
- X if (!s1 || !*s1 || !s2 || !*s2)
- X return NULL;
- X for( ; *s1; s1++) {
- X for(p = s2; *p; p++)
- X if (*p == *s1)
- X return s1;
- X }
- X return NULL;
- X}
- X
- X/* check two lists of strings each of which contain substrings.
- X * Each substring is delimited by any char in "delimiters"
- X * return true if any elements in list1 are on list2.
- X * thus:
- X * string1 = "foo, bar, baz"
- X * string2 = "foobar, baz, etc"
- X * delimiters = ", \t"
- X * example returns 1 because "baz" exists in both lists
- X * NOTE: case is ignored.
- X */
- Xchk_two_lists(list1, list2, delimiters)
- Xregister char *list1, *list2, *delimiters;
- X{
- X register char *p, c;
- X register int found = 0;
- X
- X if (p = any(list1, delimiters)) {
- X for (p++; *p && index(delimiters, *p); p++)
- X ;
- X if (chk_two_lists(p, list2, delimiters))
- X return 1;
- X }
- X if (p = any(list2, delimiters)) {
- X for (p++; *p && index(delimiters, *p); p++)
- X ;
- X if (chk_two_lists(list1, p, delimiters))
- X return 1;
- X }
- X if (p) {
- X while (index(delimiters, *(p-1)))
- X --p;
- X c = *p, *p = 0;
- X }
- X found = !lcase_strncmp(list1, list2, -1);
- X if (p)
- X *p = c;
- X return found;
- X}
- X
- Xbzero(addr, size)
- Xregister char *addr;
- Xregister int size;
- X{
- X while (size-- > 0)
- X addr[size] = 0;
- X}
- X
- X/* do an atoi() on the string passed and return in "val" the decimal value.
- X * the function returns a pointer to the location in the string that is not
- X * a digit.
- X */
- Xchar *
- Xmy_atoi(p, val)
- Xregister char *p;
- Xregister int *val;
- X{
- X int positive = 1;
- X
- X if (!p)
- X return NULL;
- X *val = 0;
- X if (*p == '-')
- X positive = -1, p++;
- X while (isdigit(*p))
- X *val = (*val) * 10 + *p++ - '0';
- X *val *= positive;
- X return p;
- X}
- X
- X/* strcmp ignoring case */
- Xlcase_strncmp(str1, str2, n)
- Xregister char *str1, *str2;
- X{
- X while (*str1 && *str2 && --n != 0)
- X if (lower(*str1) != lower(*str2))
- X break;
- X else
- X str1++, str2++;
- X return lower(*str1) - lower(*str2);
- X}
- X
- X/* strcpy converting everything to lower case (arbitrary) to ignore cases */
- Xchar *
- Xlcase_strcpy(dst, src)
- Xregister char *dst, *src;
- X{
- X register char *s = dst;
- X
- X /* "lower" is a macro, don't increment its argument! */
- X while (*dst++ = lower(*src))
- X src++;
- X return s;
- X}
- X
- X/* this strcpy returns number of bytes copied */
- XStrcpy(dst, src)
- Xregister char *dst, *src;
- X{
- X register int n = 0;
- X if (!dst || !src)
- X return 0;
- X while (*dst++ = *src++)
- X n++;
- X return n;
- X}
- X
- Xvoid
- Xxfree(cp)
- Xchar *cp;
- X{
- X extern char end[];
- X
- X if (cp >= end && cp < (char *) &cp && debug < 5)
- X free(cp);
- X}
- X
- Xchar *
- Xsavestr(s)
- Xregister char *s;
- X{
- X register char *p;
- X char *malloc();
- X if (!s)
- X s = "";
- X if (!(p = malloc((unsigned) (strlen(s) + 1)))) {
- X error("out of memory saving %s", s);
- X return NULL;
- X }
- X return strcpy(p, s);
- X}
- X
- Xvoid
- Xfree_vec(argv)
- Xchar **argv;
- X{
- X register int n;
- X if (!argv)
- X return;
- X for (n = 0; argv[n]; n++)
- X xfree(argv[n]);
- X xfree((char *)argv);
- X}
- X
- X/* copy a vector of strings into one string -- return the end of the string */
- Xchar *
- Xargv_to_string(p, argv)
- Xregister char *p, **argv;
- X{
- X register int i;
- X register char *ptr = p;
- X
- X *p = 0;
- X if (!argv[0])
- X return "";
- X for (i = 0; argv[i]; i++)
- X ptr += strlen(sprintf(ptr, "%s ", argv[i]));
- X *--ptr = 0; /* get rid of the last space */
- X return ptr;
- X}
- X
- Xchar *
- Xitoa(n)
- X{
- X static char buf[10];
- X return sprintf(buf, "%d", n);
- X}
- X
- X/*
- X * There are two different kinds of sprintf() --those that return char * and
- X * those that return int. System-V returns int (the length of the resulting
- X * string). BSD has historically returned a pointer to the resulting string
- X * instead. Mush was originally written under BSD, so the usage has always
- X * been to assume the char * method. Because the system-v method is far more
- X * useful, mush should some day change to use that method, but until then,
- X * this routine was written to allow all the unix'es to appear the same to
- X * the programmer regardless of which sprintf is actually used. The "latest"
- X * version of 4.3BSD (as of Fall 1988) has changed its format to go from the
- X * historical BSD method to the sys-v method. It is no longer possible to
- X * simply #ifdef this routine for sys-v --it is now required to use this
- X * routine regardless of which sprintf is notice to your machine. However,
- X * if you know your system's sprintf returns a char *, you can remove the
- X * define in strings.h
- X */
- X#include <varargs.h>
- X/*VARARGS*/
- X/*ARGSUSED*/
- Xchar *
- XSprintf(va_alist)
- Xva_dcl
- X{
- X char *buf, *fmt;
- X va_list ap;
- X
- X va_start(ap);
- X buf = va_arg(ap, char *);
- X fmt = va_arg(ap, char *);
- X#ifdef VPRINTF
- X (void) vsprintf(buf, fmt, ap);
- X#else
- X {
- X FILE foo;
- X foo._cnt = BUFSIZ;
- X foo._base = foo._ptr = buf; /* may have to be cast (unsigned char *) */
- X foo._flag = _IOWRT+_IOSTRG;
- X (void) _doprnt(fmt, ap, &foo);
- X *foo._ptr = '\0'; /* plant terminating null character */
- X }
- X#endif /* VPRINTF */
- X va_end(ap);
- X return buf;
- X}
- X
- Xvoid
- Xprint_argv(argv)
- Xchar **argv;
- X{
- X while (*argv)
- X if (debug)
- X printf("(%s) ", *argv++);
- X else
- X wprint("%s ", *argv++);
- X if (debug) {
- X putchar('\n');
- X fflush(stdout);
- X } else
- X wprint("\n");
- X}
- X
- X/*
- X * putstring -- put a string into a file. Expand \t's into tabs and \n's
- X * into newlines. Append a \n and fflush(fp);
- X */
- Xvoid
- Xputstring(p, fp)
- Xregister char *p;
- Xregister FILE *fp;
- X{
- X for ( ; *p; ++p)
- X if (*p != '\\')
- X fputc(*p, fp);
- X else
- X switch(*++p) {
- X case 'n': fputc('\n', fp);
- X when 't': fputc('\t', fp);
- X otherwise: fputc(*p, fp);
- X }
- X fputc('\n', fp);
- X fflush(fp);
- X}
- X
- X#define chtoi(c) ((int)(c) - (int)'0')
- X
- X/* m_xlate(str) converts strings of chars which contain ascii representations
- X * of control characters appearing in str into the literal characters they
- X * represent. The usual curses-mode character expansions (\Cx -> control-x)
- X * are honored, as are most C escapes. Unrecognized portions are unchanged.
- X */
- Xchar *
- Xm_xlate (str)
- Xregister char *str;
- X{
- X register char *r, *s, *t;
- X int dv, nd;
- X
- X /*
- X * r will receive the new string, s will track the old one,
- X * and t will step through escape sequences
- X * This allows the translation to be done in place
- X */
- X r = s = str;
- X while (s && *s) {
- X if (*s == '\\') {
- X t = s + 1;
- X /*
- X * After each case below, t should point to the character
- X * following the escape sequence
- X */
- X switch(*t) {
- X case '\0' :
- X /*
- X * Hmmm ... a backslash followed by the string
- X * terminator. Copy the backslash ONLY.
- X */
- X *r++ = *s++;
- X break;
- X case '0' :
- X case '1' :
- X case '2' :
- X case '3' :
- X case '4' :
- X case '5' :
- X case '6' :
- X case '7' :
- X /*
- X * Convert up to 3 octal digits to their ascii value
- X */
- X dv = chtoi(*t++);
- X for (nd = 0; (isdigit(*t) && (nd < 2)); nd++)
- X if (chtoi(*t) < 8)
- X dv = (8 * dv) + chtoi(*t++);
- X else
- X break;
- X if (dv < 256 && dv > 0)
- X /* Valid octal number escaped */
- X *r++ = (char)dv;
- X else
- X /* Invalid octal number, so copy unchanged */
- X while (s < t)
- X *r++ = *s++;
- X break;
- X case 'b' :
- X *r++ = '\b';
- X t++;
- X break;
- X case 'C' :
- X t++;
- X if (*t == '?')
- X *r++ = '\177';
- X else if (*t == '~')
- X *r++ = '\036';
- X else if (*t == '/')
- X *r++ = '\037';
- X else if (isalpha(*t) || *t > '\132' && *t < '\140')
- X *r++ = *t & 037;
- X else
- X while (s <= t) *r++ = *s++;
- X t++;
- X break;
- X case 'E' :
- X *r++ = '\033';
- X t++;
- X break;
- X case 'f' :
- X *r++ = '\f';
- X t++;
- X break;
- X case 'n' :
- X *r++ = '\n';
- X t++;
- X break;
- X case 'r' :
- X *r++ = '\r';
- X t++;
- X break;
- X case 't' :
- X *r++ = '\t';
- X t++;
- X break;
- X case '\\' :
- X *r++ = *t++;
- X break;
- X default :
- X /*
- X * Not recognized, so copy both characters
- X */
- X *r++ = *s++;
- X *r++ = *s++;
- X break;
- X }
- X /*
- X * Now make sure s also points to the character after the
- X * escape sequence, by comparing to t
- X */
- X if (t > s)
- X s = t;
- X } else
- X *r++ = *s++;
- X }
- X *r = '\0';
- X return str;
- X}
- X
- X/*
- X * Convert control characters to ascii format (reverse effect of m_xlate()).
- X */
- Xchar *
- Xctrl_strcpy(s_out, s_in, bind_format)
- Xregister char *s_out, *s_in;
- X{
- X extern char *_unctrl[];
- X char *start = s_out;
- X
- X for (; *s_in; s_in++)
- X if (*s_in == '\n')
- X *s_out++ = '\\', *s_out++ = 'n';
- X else if (*s_in == '\r')
- X *s_out++ = '\\', *s_out++ = 'r';
- X else if (*s_in == '\t')
- X *s_out++ = '\\', *s_out++ = 't';
- X else if (*s_in == ESC)
- X *s_out++ = '\\', *s_out++ = 'E';
- X else if (iscntrl(*s_in)) {
- X if (bind_format)
- X *s_out++ = '\\', *s_out++ = 'C';
- X else
- X *s_out++ = '^';
- X *s_out++ = _unctrl[*s_in][1];
- X } else
- X *s_out++ = *s_in;
- X *s_out = 0;
- X return start;
- X}
- END_OF_FILE
- if test 9787 -ne `wc -c <'strings.c'`; then
- echo shar: \"'strings.c'\" unpacked with wrong size!
- fi
- # end of 'strings.c'
- fi
- echo shar: End of archive 5 \(of 19\).
- cp /dev/null ark5isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 19 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-